package cn.mayaslight.common.springbean;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.http.HttpResponse;
import org.springframework.stereotype.Component;

import cn.mayaslight.common.handler.IHandler;
import cn.mayaslight.common.http.RequestBuilderPack;
import cn.mayaslight.common.param.IParamIn;
import cn.mayaslight.common.proxy.CallerProxy;
import cn.mayaslight.common.utils.SyncUtils;

@Component
public class APICaller {

	@Resource
	private HttpAPIGetter apiGetter;

	private static APICaller caller = null; 
	private static final Object LOCK = new Object();
	
	public static final int GET = 0;
	public static final int POST = 1;
	public static final int JSON = 0;
	public static final int XML = 1;
	public static final String HTTP_URL_GET_PREFIX = "get:";
	public static final String HTTP_URL_POST_PREFIX = "post:";
	public static final String HTTP_URL_JSON_PREFIX = "json:";
	public static final String HTTP_URL_XML_PREFIX = "xml:";
	public static final String ENTITY_TYPE_STRING = "ENTITY_TYPE_STRING";
	
	private APICaller() {
		
	}
	
	@PostConstruct
	public void init () {
		caller = this;
	}
	
	public static HttpResponse call(IParamIn param){
		return getCaller(null).doCall(param, null);
	}
	
	public static <T> T call(IParamIn param, Class<T> clazz){
		return getCaller(null).doCall(param, clazz);
	}
	
	public static <T> T call(IParamIn param, Class<T> clazz, HttpAPIGetter apiGetter){
		return getCaller(apiGetter).doCall(param, clazz);
	}
	
	private static APICaller getCaller(final HttpAPIGetter apiGetter) {
		caller = SyncUtils.sync(caller, APICaller.class, LOCK, null, new IHandler<APICaller, APICaller>() {

			@Override
			public APICaller handle(APICaller e) {
				return new APICaller().setApiGetter(apiGetter);
			}
			
		});
		return caller;
	}
	
	private <T> RequestBuilderPack<T> generateRequestBuilder(IParamIn param) {
		return RequestBuilderPack.create(param, apiGetter);
	}
	
	private <T> RequestBuilderPack<T> generateRequestBuilder(IParamIn param, Class<T> targetClass) {
		return RequestBuilderPack.create(param, apiGetter, targetClass);
	}
	
	public HttpResponse doCall(IParamIn param) {
		return CallerProxy
				.create(generateRequestBuilder(param))
				.addParameter(param)
				.setEntity(param)
				.build()
				.execute();
	}
	
	public <T> T doCall(IParamIn param, Class<T> clazz) {
		return CallerProxy
				.create(generateRequestBuilder(param, clazz))
				.addHeader(param)
				.addParameter(param)
				.setEntity(param)
				.build()
				.executeWithHandler();
	}

	public HttpAPIGetter getApiGetter() {
		return apiGetter;
	}

	public APICaller setApiGetter(HttpAPIGetter apiGetter) {
		this.apiGetter = apiGetter;
		return this;
	}
	
}
